package com.bezdelnick.forum.web.component;

import com.bezdelnick.forum.domain.AppUser;
import com.bezdelnick.forum.service.ForumService;
import com.bezdelnick.forum.validator.UserExistValidator;
import com.bezdelnick.forum.web.page.ModeratorPage;
import com.bezdelnick.forum.web.page.ErrorPage;
import com.bezdelnick.forum.web.page.LoginPage;
import org.apache.wicket.Component;
import org.apache.wicket.markup.html.form.*;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.apache.wicket.spring.injection.annot.SpringComponentInjector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.util.HtmlUtils;

/**
 * Created by IntelliJ IDEA.
 * User: Bezdelnick
 * Date: 16.08.12
 * Time: 23:36
 * To change this template use File | Settings | File Templates.
 */
public class RegistrationForm extends Form<AppUser> {
    private static final Logger LOGGER = LoggerFactory.getLogger(RegistrationForm.class);

    private ForumService.MODE mode;

    private AppUser appUser;

    @SpringBean
    @SuppressWarnings("unused")
    private ForumService forumService;

    public RegistrationForm(String id, ForumService.MODE mode) {
        super(id);
        /* Add this instance to Spring context */
        SpringComponentInjector.get().inject(this);

        this.mode = mode;

        setModel(new CompoundPropertyModel(new AppUser()));

        FormComponent<String> rtfUserName = new RequiredTextField("username");
        rtfUserName.add(new UserExistValidator());
        addErrorLabel(rtfUserName);

        add(rtfUserName);
        add(new EmailTextField("email"));
        add(new PasswordTextField("password"));
    }

    @Override
    protected void onSubmit() {
        boolean successful = true;

        try {
            appUser = getModelObject();
            switch (mode) {
                case ADMIN:
                    this.addNewAdmin(appUser);
                    break;
                case USER:
                    this.addNewUser(appUser);
                    break;
            }

        } catch (Exception ex) {
            LOGGER.warn(ex.getMessage());
            successful = false;
        }

        if (successful) {
            switch (mode) {
                case ADMIN:
                    redirectToInterceptPage(new ModeratorPage());
                    break;
                case USER:
                    PageParameters pageParameters = new PageParameters();
                    pageParameters.add("userRequest", "ok");
                    LoginPage loginPage = new LoginPage(pageParameters);
                    redirectToInterceptPage(loginPage);
                    break;
            }
        } else {
            PageParameters pageParameters = new PageParameters();
            pageParameters.add("error", "Unknown error adding user");
            ErrorPage errorPage = new ErrorPage(pageParameters);
            redirectToInterceptPage(errorPage);
        }
    }

    private void addErrorLabel(Component component) {
        add(new FeedbackLabel(component.getId() + "Error", component));
    }

    private boolean addNewUser(AppUser user) {
        try {
            AppUser userInDatabase = forumService.getAppUserDao().getUserByName(user.getUsername());
            if (userInDatabase == null && user != null) {

                user.setUsername(
                        HtmlUtils.htmlEscape(user.getUsername())
                );
                user.setEnabled(true);

                if (forumService.getAppUserDao().insertUser(user) &&
                        forumService.getRoleDao().insertRoleUSERForUserByUserId(user.getId())) {
                    setModelObject(new AppUser());
                }
            }
            return true;
        } catch (Exception e) {
            LOGGER.error(e.getMessage());
            return false;
        }
    }

    private boolean addNewAdmin(AppUser user) {
        try {
            AppUser userInDatabase = forumService.getAppUserDao().getUserByName(user.getUsername());
            if (userInDatabase == null && user != null) {

                user.setUsername(
                        HtmlUtils.htmlEscape(user.getUsername())
                );
                user.setEnabled(false);

                if (forumService.getAppUserDao().insertUser(user) &&
                        forumService.getRoleDao().insertRoleADMINForUserByUserId(user.getId())) {
                    setModelObject(new AppUser());
                }
            }
            return true;
        } catch (Exception e) {
            LOGGER.error(e.getMessage());
            return false;
        }
    }
}
